package com.jacob.androidstudy.androidnote.contentprovider;

import android.app.Activity;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.Settings;


/**
 * ContentProvider：
 * 1 ContentProvider是Android提供的，多个程序间数据交互的唯一机制。通过ContentProvider，无需了解存储细节，就可以实现数据存储及共享。
 * 2 例如，“联系人数据”是“通讯录”程序的私有数据。但是，很多情况下，其他程序也需要访问“联系人数据”。“通讯录”软件就会通过ContentProvider的方式对外提供API，让别的软件访问“联系人数据”。
 * 3 安装程序时，系统会去注册程序定义的ContentProvider，系统启动后会监听所有对ContentResolver的请求，然后启动对应ContentResolver进程。
 * 4 Android本身提供了管理数据（包括音频、视频、图片、通讯录等）的ContentProvider，可以在API文档的android.provider包下找到。
 * 
 * 
 */
public class Android四大组件之ContentProvider extends Activity {
	
	/**
	 * ContentURI
	 * 是ContentProvider中，用来识别数据的URI。
	 * 它由前缀（content://）、权限部分（ContentProvider的授权名）、路径（表名）和数字（ID）构成。例如：“content://user_dictionary/words/34”。
	 * 
	 * 
	 * 
	 */
	public void AboutURI() {
//		将String转换成Uri对象
		Uri.parse("content://user_dictionary/words/34");
		
//		给URI结尾加上ID
		ContentUris.withAppendedId(null, 100);
//		从URI地址中提取ID
		ContentUris.parseId(null);
		
		
		
	}
	
	/**
	 * 使用ContentResolver来调用ContentProvider
	 * 要从ContentProvider检索数据，程序需要对应的读权限。
	 * 在程序的AndroidManifest.xml中使用<uses-permission android:name="wangchao.lesson.provider.contentproviderclassname"/>标签来申请权限。用户在安装程序时，进行授权。
	 * 
	 */
	public void AboutContentResolver() {
//		1 得到ContentResolver对象
		ContentResolver contentResolver = this.getContentResolver();
		
//		2 对系统提供的ContentProvider进行数据操作
//		查询数据
//		参数1：ContentProvider的URI，到android.provider下找系统提供的ContentProvider。常见的有：Browser、CallLog、ContactsContract、Calendar、MediaStore、Settings、UserDictionary。
//		参数2：查询字段的列表，传入null返回所有字段（效率低）。系统ContentProvider的字段，一般都在类内部定义为常量了。
//		参数3：where条件（不包括WHERE关键字），传入null返回所有行。
//		参数4：一个字符串数组，系统会用数组元素依次替换参数3中的问号。这种转义在使用时，只能用于原本应该是字符串出现的地方。
//		参数5：ORDER BY条件（不包括ORDER BY关键字），传入null使用默认排序。
		Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts.DISPLAY_NAME}, "Selection", new String[]{"SelectionArgs"}, "ORDER BY...");
//		查询结果和当前Activity绑定，这样Activity回收时，Cursor也会被回收，然后ContentProvider测才会关闭数据库连接。
		this.startManagingCursor(cursor);
		
//		插入数据
//		参数1：ContentProvider的URI，到android.provider下找系统提供的ContentProvider。常见的有：Browser、CallLog、ContactsContract、Calendar、MediaStore、Settings、UserDictionary。
//		参数2：插入的字段名和字段值。ContentValues对象，类似一个map，通过键值对的形式存储。
//		返回值：新插入记录的ContentUri，例如：content://user_dictionary/words/<id_value>。
		ContentValues values = new ContentValues();
		values.put("ColumnName", "Values");
		values.put("ColumnName", 200);
		contentResolver.insert(ContactsContract.Contacts.CONTENT_URI, values);
		
//		修改数据
//		参数1：ContentProvider的URI，到android.provider下找系统提供的ContentProvider。常见的有：Browser、CallLog、ContactsContract、Calendar、MediaStore、Settings、UserDictionary。
//		参数2：修改的字段名和字段值。ContentValues对象，类似一个map，通过键值对的形式存储。
//		参数3：where条件（不包括WHERE关键字），传入null修改所有行。
//		参数4：一个字符串数组，系统会用数组元素依次替换参数3中的问号。这种转义在使用时，只能用于原本应该是字符串出现的地方。
//		返回值：修改的记录数量
		contentResolver.update(ContactsContract.Contacts.CONTENT_URI, values, "Selection", new String[]{"SelectionArgs"});
		
//		删除数据
//		参数1：ContentProvider的URI，到android.provider下找系统提供的ContentProvider。常见的有：Browser、CallLog、ContactsContract、Calendar、MediaStore、Settings、UserDictionary。
//		参数2：where条件（不包括WHERE关键字），传入null删除所有行。
//		参数3：一个字符串数组，系统会用数组元素依次替换参数3中的问号。这种转义在使用时，只能用于原本应该是字符串出现的地方。
//		返回值：删除的记录数量
		contentResolver.delete(ContactsContract.Contacts.CONTENT_URI, "Selection", new String[]{"SelectionArgs"});
		
		
	}
	
	
	/**
	 * CreatingContentProvider
	 * 
	 * 
	 */
	public void AboutCreatingContentProvider() {
//		1 在其他类中实现数据库的增删查改功能，ContentProvider本身不应该直接操作数据库。
		
//		2 定义一个类，并继承与ContentProvider，然后在AndroidManifest.xml中注册。
/*        <provider android:name=".ContentProviderClassName" --ContentProvider的实现类名
                android:authorities="wangchao.lesson.provider.contentproviderclassname" --ContentProvider的授权名，一般用包名+类名（小写）。不加这个属性，其他程序就无法调用这个ContentProvider。
                android:multiprocess="true" --是否允许其他进程访问
                ></provider>*/
		
		class MyContentProvider extends ContentProvider {
//			3 在类中定义ContentProvider的URI常量
//			public static final Uri CONTENT_URI = Uri.parse("wangchao.lesson.provider.contentproviderclassname");
			
//			4 定义UriMatcher对象
//			参数1：ContentProvider的默认授权URI对应的编码。
			UriMatcher uriMatcher = new UriMatcher(0);

			/**
			 * 系统实例化ContentProvider后，立刻调用本方法对其初始化。
			 * 
			 */
			@Override
			public boolean onCreate() {
//				创建UriMatcher对象
				this.uriMatcher = new UriMatcher(0);
				
//				为所有需要匹配的URI地址映射编码值
//				参数1：ContentProvider的默认授权URI
//				参数2：路径。可以使用通配符，“*”表示任意长度的字符，“#”表示任意长度的数字。
//				参数3：编码值。
				this.uriMatcher.addURI("wangchao.lesson.provider.contentproviderclassname", "*table", 1);
				this.uriMatcher.addURI("wangchao.lesson.provider.contentproviderclassname", "table/#", 2);
				
				return false;
			}
			
			/**
			 * 查找数据
			 * 参数1：查找目标的URI
			 * 参数2：目标字段
			 * 参数3：where条件（不包括WHERE关键字），传入null修改所有行。
			 * 参数4：一个字符串数组，表示数组元素依次替换参数3中的问号。
			 * 参数5：ORDER BY条件（不包括ORDER BY关键字）。
			 * 返回值：查找结果。
			 * 
			 * 
			 */
			@Override
			public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
//				判断ContentUri编码，根据编码进行不同的数据查询
				if (this.uriMatcher.match(uri) == 0) {
					
				} else if (this.uriMatcher.match(uri) == 1) {
					
				} else if (this.uriMatcher.match(uri) == 2) {
					
				} else {
					
				}
				
//				返回查询结果
				return null;
			}
			
			@Override
			public Uri insert(Uri uri, ContentValues values) {
				return null;
			}
			
			@Override
			public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
				return 0;
			}
			
			@Override
			public int delete(Uri uri, String selection, String[] selectionArgs) {
				return 0;
			}
			
			@Override
			public String getType(Uri uri) {
				return null;
			}
			
			
		}
	}
	

}
